<template>
  <vxe-modal v-model="state.visible" v-bind="state.config" @close="state.visible = false">
    <template #title>
      鸟啼
    </template>
    <template #default>
      <div class="full sys-form relative p-6 mini-scroll overflow-y-auto" v-if="!state.config.loading">
        <a-form ref="formRef" :layout="state.layout" :model="formData" v-bind="state.layout==='horizontal'?{labelCol: {span: 5,},wrapperCol:{span: 19,}}:{}">
          <div class="grid grid-cols-1 gap-2">
            <a-form-item label="菜单类型" name="type" :rules="[{ required: true, message: '请填写' }]">
              <a-radio-group :disabled="state.modelType === 2?true:false" v-model:value="formData.type" button-style="solid" @change="menuTypeChange">
                <a-radio-button :value="0">目录</a-radio-button>
                <a-radio-button :value="1">菜单</a-radio-button>
                <a-radio-button :value="2">操作</a-radio-button>
              </a-radio-group>
            </a-form-item>
            <a-form-item :label="state.menuName+'名称'" name="name" :rules="[{ required: true, message: '请填写',pattern:$pattern.exist }]">
              <d-input :disabled="state.modelType === 2?true:false" v-model:value="formData.name" />
            </a-form-item>
            <a-form-item :label="formData.type===2?'上级菜单':'上级目录'" name="parentId" :rules="[{ required: formData.type===2?true:false, message: '请填写' }]">
              <formSelectTree :disabled="state.modelType === 2?true:false" v-model:value="formData.parentId" :options="state.options"></formSelectTree>
            </a-form-item>
            <a-form-item label="排序号" name="order" :rules="[{ required: true, message: '请填写' }]">
              <d-number :disabled="state.modelType === 2?true:false" v-model:value="formData.order" />
            </a-form-item>
            <a-form-item v-if="state.menuName !== '操作'" :label="state.menuName+'图标'" name="icon" :rules="[{ required: true, message: '请填写' }]">
              <d-input :disabled="state.modelType === 2?true:false" v-model:value="formData.icon" />
            </a-form-item>
            <a-form-item :label="state.menuName+'权限'" v-if="state.menuName !== '目录'" name="code" :rules="[{ required: true, message: '请填写' }]">
              <a-tooltip>
                <template #title>
                  权限标识配置说明：<br />
                  ; 作为权限编码分隔符<br />
                  : 作为功能层级分隔符<br />
                  , 作为多个功能点的分隔符<br />
                  * 作为任意通配符<br />
                  例如：<br />
                  sys:menu:add<br />
                  sys:user:add;sys:role:add<br />
                  sys:msg:add,edit<br />
                  sys:log:*
                </template>
                <d-input :disabled="state.modelType === 2?true:false" v-model:value="formData.code" />
              </a-tooltip>
            </a-form-item>
            <a-form-item v-if="state.menuName !== '操作'" :label="state.menuName+'路径'" name="extension" :rules="[{ required: true, message: '请填写',validator:(_,obj)=>{return $XEUtils.customCheck(_,obj,'url')}}]">
              <d-input :disabled="state.modelType === 2?true:false" v-model:value="formData.extension.url" placeholder="请以“/” 开头，例如：/system" />
            </a-form-item>
            <a-row :gutter="24">
              <a-col :span="12">
                <a-form-item :labelCol="{span: 10}" label="是否启用" name="show" :rules="[{ required: true, message: '请填写' }]">
                  <formRadio :disabled="state.modelType === 2?true:false" v-model:value="formData.show" :options="[{label:'是',value:true},{label:'否',value:false}]" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item :labelCol="{span: 10}" v-if="state.menuName !== '操作'" label="是否显示" name="extension" :rules="[{ required: true, message: '请填写',validator:(_,obj)=>{return $XEUtils.customCheck(_,obj,'show')}}]">
                  <formRadio :disabled="state.modelType === 2?true:false" v-model:value="formData.extension.show" :options="[{label:'是',value:'是'},{label:'否',value:'否'}]" />
                </a-form-item>
              </a-col>
            </a-row>
          </div>
        </a-form>
      </div>
      <div v-else class="flex-center">
        <a-spin />
      </div>
    </template>
    <template #footer v-if="state.modelType !== 2">
      <div class="flex justify-center p-3">
        <a-space :size="10">
          <a-button :disabled="state.submitState" type="primary" @click="onSubmit">{{state.submitState?'提交中':'提交'}}</a-button>
          <a-button :disabled="state.submitState" @click="formRef.resetFields()">重置</a-button>
        </a-space>
      </div>
    </template>
  </vxe-modal>
</template>
<script setup>
import { modelConfig } from '@/javascript/antdesign/modelConfig'
import { reactive, toRefs, getCurrentInstance, watch, computed } from 'vue'
const prototype = getCurrentInstance().appContext.config.globalProperties
const emits = defineEmits(['save'])
const state = reactive({
  //窗口
  config: XEUtils.clone(modelConfig, true),
  modelType: 0, //0-新增 1-编辑 2-详情
  submitState: false,
  loading: false,
  visible: false,
  //表单
  formRef: null,
  layout: 'horizontal', //排版方式 horizontal | vertical
  formData: {
    parentId: undefined,
    extension: {},
  },
  //业务
  menuName: undefined, //新增的菜单类型
  options: [], //树结构菜单数据
})

//切换菜单类型后，改变树结构可选状态，清空已选值
const menuTypeChange = (val) => {
  state.formData.parentId = undefined
  state.options = dataJS(state.options)
}

//上级菜单数据处理
const dataJS = (datas) => {
  let newArray = XEUtils.clone(XEUtils.toTreeArray(datas), true)
  newArray.forEach((element) => {
    element.label = element.name
    element.value = element.id
    element.disabled = false
    //目录和菜单只能建在目录下
    if (state.formData.type === 0 || state.formData.type === 1) {
      if (element.type === 1) {
        element.disabled = true
      }
    }
    if (state.formData.type === 2) {
      if (element.type === 2) {
        element.disabled = true
      }
    }

    //父级菜单不可以选择当前正在编辑的菜单
    if (element.id === state.formData.id) {
      element.disabled = true
    }
  })
  return XEUtils.toArrayTree(newArray)
}
//获取上级菜单树结构
function getTreeMenuData() {
  return new Promise((resolve, reject) => {
    state.options = []
    axios.get('system/menu/listAllMenus').then((res) => {
      if (!res.success) return
      state.options = dataJS(res.data)
      resolve()
    })
  })
}
//提交
const onSubmit = () => {
  state.formRef.validateFields().then((values) => {
    state.loading = true
    if (state.modelType === 0) {
      axios.postJson('system/menu/create', values).then((res) => {
        state.loading = false
        if (res.success) {
          state.visible = false
          emits('save')
        }
      })
    } else {
      values.id = state.formData.id
      axios.postJson('system/menu/update', values).then((res) => {
        state.loading = false
        if (res.success) {
          state.visible = false
          emits('save')
        }
      })
    }
  })
}
//查看
async function viewFun(datas) {
  state.formData = XEUtils.clone(datas, true)
  await getTreeMenuData()
  state.loading = false
}
//创建
async function createFun() {
  state.formData = {
    extension: {},
  }
  state.formData.type = 1
  state.formData.show = true
  state.formData.extension.show = '是'
  await getTreeMenuData()
  state.loading = false
}
//编辑
async function saveFun(datas) {
  let dataNew = XEUtils.clone(datas, true)
  delete dataNew.children
  delete dataNew._X_ROW_CHILD
  state.formData = dataNew
  await getTreeMenuData()
  state.loading = false
}

const openModel = (type = 0, datas = undefined) => {
  //初始化窗口
  state.config.id = '新增菜单'
  state.config.remember = false
  state.config.width = 600
  state.config.height = 'auto'
  state.visible = true
  state.loading = true
  state.modelType = type
  //新增|编辑|详情 操作
  type === 0 ? createFun() : type === 1 ? saveFun(datas) : viewFun(datas)
}

// 常用
watch(
  () => state,
  (newArr) => {},
  { deep: true, immediate: true }
)
state.menuName = computed(() => {
  return state.formData.type === 0 ? '目录' : state.formData.type === 1 ? '菜单' : '操作'
})
//导出
defineExpose({
  openModel,
})

const { formRef, formData } = toRefs(state)
</script>